算术表达式是每一种编程语言的一部分。下面是一个叫做calc的算术表达式计算语言的例子。calc表达式会编译到一个应用程序中，计算以下表达式:\par

\begin{tcolorbox}[colback=white,colframe=black]
with a, b: a * (4 + b)
\end{tcolorbox}

表达式中使用的变量必须用with关键字声明。这个程序可以编译成应用程序，它向用户询问a和b变量的值并打印结果。\par

简单的示例总是受欢迎的，但作为编译器作者，需要比这更全面的规范来实现和测试。编程语言语法的载体是语法。\par

\hspace*{\fill} \par %插入空行
\textbf{指定编程语言语法的形式}

语言的元素，如：关键字、标识符、字符串、数字和操作符，称为标记。其实，程序是一个标记序列，语法指定哪些序列是有效的。\par

通常，语法是用扩展的巴科斯-诺尔范式(EBNF)编写的。其中一个语法规则是有一个左手边和一个右手边。左边只是一个叫做非终结符的符号，右手边包括用于替代和重复的非终结符、标记和元符号。来看看calc语言的语法:\par

\begin{tcolorbox}[colback=white,colframe=black]
calc : ("with" ident ("," ident)* ":")? expr ; \\
expr : term (( "+" | "-" ) term)* ; \\
term : factor (( "*" | "/") factor)* ; \\
factor : ident | number | "(" expr ")" ; \\
ident : ([a-zAZ])+ ; \\
number : ([0-9])+ ; 
\end{tcolorbox}

第一行中，calc是非终止符。如果没有特别说明，则语法的第一个非结束符是开始符号。冒号，:，是规则左边和右边之间的分隔符。"，"， "和":"是表示该字符串的标记。括号用于分组，组是可选的，也可以重复。右括号后的问号?表示可选组。星号*表示零次或多次重复，而加号+表示一次或多次重复。ident和expr是非终止符。每一个，都对应另一个规则。分号;表示规则的结束。第二行中的管道|表示一个替代方案。最后，最后两行中的括号[]表示字符类。有效字符写在括号内，例如：[a-zA-Z]字符类匹配一个大写字母或小写字母，([a-zA-Z])+匹配这些字母中的一个或多个。这相当于正则表达式。\par

\hspace*{\fill} \par %插入空行
\textbf{语法对于编译器作者的帮助}

首先，定义了所有标记，这是创建词法分析器所需要的，语法规则可以翻译成解析器。当然，如果出现关于解析器是否正确工作的问题，那么语法可以作为一个很好的规范。\par

然而，语法并不是定义编程语言的所有方面，语法的意义(语义)也必须定义。为此目的也开发了语法形式，类似于最初引入该语言，通常在纯文本中指定。\par

掌握了这些知识后，接下来的两节将展示词法分析如何将输入转换为标记序列，以及如何用C++编写语法，从而进行语法分析。\par

























